package com.hsh.config.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.hsh.tools.DateUtils2;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.TimeZone;

/**
 * <p>
 * JacksonConfig
 * </p>
 *
 * @author huangsihai
 * @date 2021/7/20
 */
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.locale(Locale.CHINA)
                .timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()))
                .simpleDateFormat(DateUtils2.YYYY_MM_DD_HH_MM_SS)
                .modules(new CustomJavaTimeModule());
    }

    /**
     * 配置java8 time的序列化器和反序列化器
     */
    private static class CustomJavaTimeModule extends SimpleModule {

        public CustomJavaTimeModule() {
            super(PackageVersion.VERSION);
            final DateTimeFormatter dateTimeFormatterYyyyMmDdHhMmSs = DateTimeFormatter.ofPattern(DateUtils2.YYYY_MM_DD_HH_MM_SS);
            final DateTimeFormatter dateTimeFormatterYyyyMmDd = DateTimeFormatter.ofPattern(DateUtils2.YYYY_MM_DD);
            final DateTimeFormatter dateTimeFormatterHhMmSs = DateTimeFormatter.ofPattern(DateUtils2.HH_MM_SS);

            this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatterYyyyMmDdHhMmSs));
            this.addSerializer(LocalDate.class, new LocalDateSerializer(dateTimeFormatterYyyyMmDd));
            this.addSerializer(LocalTime.class, new LocalTimeSerializer(dateTimeFormatterHhMmSs));

            this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatterYyyyMmDdHhMmSs));
            this.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateTimeFormatterYyyyMmDd));
            this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(dateTimeFormatterHhMmSs));
        }
    }
}
